package models

import (
	"time"
	"github.com/jinzhu/gorm"
)

type Permission struct {
	ID   int    `gorm:"primary_key" json:"id"`
	Name string `json:"name"`
	//ParentId    sql.NullInt64 `json:"parent_id"`
	ParentId    int           `json:"parent_id"`
	DisplayName string        `json:"display_name"`
	ApiUrl      string        `json:"api_url"`
	FrontUrl    string        `json:"front_url"`
	Description string        `json:"description"`
	Action      string        `json:"action"`
	Method      string        `json:"method"`
	Icon        string        `json:"icon"`
	Component   string        `json:"component"`
	IsMenu      int           `json:"is_menu"`
	CreatedAt   time.Time     `json:"created_at"`
	Sort        int           `json:"sort"`
	UpdatedAt   time.Time     `json:"updated_at"`
	Sub         []*Permission `json:"sub,omitempty"`
}

type PermissionRole struct {
	PermissionId int `json:"permission_id"`
	RoleId       int `json:"role_id"`
}

func (p Permission) TableName() string {
	return "permissions"
}

func (pr PermissionRole) TableName() string {
	return "permission_role"
}

func GetPermissionAll() []*Permission {
	var data []*Permission

	_ = DB.Table("permissions").Find(&data).Error

	list := buildDate(data)
	m := makeTreeCore(0, list)
	return m
}

// 获取角色对应的所有权限
func GetRolePermissionList(role_id int) []*Permission {
	var data []*Permission
	_ = DB.Table("permission_role").Joins("left Join permissions on permission_role.permission_id = permissions.id").Where("permission_role.role_id=?", role_id).Select("permissions.*").Order("permissions.parent_id desc, sort asc").Find(&data)
	list := buildDate(data)
	m := makeTreeCore(0, list)
	return m
}

func buildDate(list []*Permission) (map[int]map[int]*Permission) {
	data := make(map[int]map[int]*Permission)
	for _, v := range list {
		id := v.ID
		fid := v.ParentId
		if _, ok := data[fid]; !ok {
			data[fid] = make(map[int]*Permission)
		}
		data[fid][id] = v
	}
	return data
}

func makeTreeCore(index int, data map[int]map[int]*Permission) []*Permission {
	tmp := make([]*Permission, 0)
	for id, item := range data[index] {
		if data[id] != nil {
			item.Sub = makeTreeCore(id, data)
		}
		tmp = append(tmp, item)
	}
	return tmp
}

// 通过parent_id 获取子权限
func GetPermissionsChilds(parent_id int) ([]*Permission, error) {
	var data []*Permission
	err := DB.Table("permissions").Where("parent_id=?", parent_id).Order("sort asc").Find(&data).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}
	return data, nil
}

// 添加权限

func (a *Permission) AddPermission() error {
	if err := DB.Table("permissions").Create(&a).Error; err != nil {
		return err
	}
	return nil
}

// 修改权限

func (a *Permission) UpdatePermission() error {
	data := map[string]interface{}{
		"name":         a.Name,
		"parent_id":    a.ParentId,
		"display_name": a.DisplayName,
		"api_url":      a.ApiUrl,
		"front_url":    a.FrontUrl,
		"description":  a.Description,
		"action":       a.Action,
		"method":       a.Method,
		"icon":         a.Icon,
		"component":    a.Component,
		"updated_at":   a.CreatedAt,
		"is_menu":      a.IsMenu,
		"sort":         a.Sort,
	}
	err := DB.Table("permissions").Where("id=?", a.ID).Updates(data).Error
	if err != nil {
		return err
	}
	return nil
}

// 查看单个

func (a *Permission) GetPermissionById() (*Permission, error) {

	var data Permission
	err := DB.Table("permissions").Where("id=?", a.ID).First(&data).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}
	return &data, nil
}

// 删除

func DeletedPermission(id int) error {
	err := DB.Delete(Permission{}, "id=?", id).Error
	if err != nil {
		return err
	}
	return nil
}

func GetPermissionByUser(admin *AdminDetailsResult, url string, method string) (*Permission) {
	var permission Permission
	err := DB.Table("permissions").Where("`id` IN (SELECT `permission_id` FROM `permission_role` WHERE `role_id` IN (SELECT `role_id` FROM `admin_role` WHERE `admin_id`=?)) AND `api_url`=? AND `method`=?", admin.ID, url, method).First(&permission).Error
	if err != nil || err == gorm.ErrRecordNotFound {
		return nil
	}
	return &permission
}
